Contents page

Rules for Tools/Event Structure


Event Structure

Bars&Pipes uses the Event structure to describe MIDI events, both as they flow through the PipeLine, and when they are recorded in a Track:

struct Event {
    struct Event *next;     /* Next Event in list. */
    long time;              /* When this Event occurs. */
    char type;              /* What type of Event. */
    unsigned char status;   /* MIDI status. */
    unsigned char byte1;    /* First byte of data. */
    unsigned char byte2;    /* Second byte of data. */
    long data;              /* Extra storage. */
    struct Tool *tool;      /* Tool to process this. */ };

`next'
     This points to the next Event in the linked list of Events that
     make up a sequence.  Almost all Bars&Pipes data structures are
     arranged in linked lists.  This provides a great degree of
     flexibility because linked lists can be any length.  Also, since
     the pointer to the next record in a Bars&Pipes linked list is
     always the first field of the structure, Bars&Pipes can use
     generic list handling routines to process different types of
     linked lists.

`time'
     This specifies the absolute time of the Event.  Bars&Pipes
     measures time in clocks, with 192 clocks per quarter note.  An
     example time of 384 corresponds to the beginning of the third beat
     of measure one in the song.  `time' is very useful because you can
     write Tools that alter the timing of events by changing this
     number.  Good examples are the Quantize and Delay Tools.  If the
     transport is not rolling when an event occurs, time contains a
     negative number.

`type'
     This specifies what type of data is stored in the Event.  Choices
     include `EVENT_VOICE', for a MIDI performance Event, and
     `EVENT_LYRIC', for a Lyric in the Song Parameters.  Only
     `EVENT_VOICE' Events flow through the PipeLine; therefore Tools
     need only concern themselves with this one type.  When a Tool is
     in a ToolPad, it receives Events with the `EVENT_PADEDIT' bit set,
     in addition to `EVENT_VOICE'.  The `EVENT_PADEDIT' bit tells the
     Tool that it is processing a static note in a sequence, rather
     than a real-time note flowing through a PipeLine. See Event Types.

`status' `byte1' `byte2'
     If this is a MIDI Event, these three bytes carry the actual MIDI
     data.  `status' determines the actual MIDI Event type, while
     `byte1' and `byte2' carry the appropriate data.  The MIDI spec
     breaks status down into two nibbles: the high nibble selects the
     type of Event, while the low nibble selects one of sixteen MIDI
     channels.  Bars&Pipes, because its PipeLine does not recognize
     MIDI channels, always clears the low nibble.  In case you don't
     have the MIDI spec, here's a rundown on the MIDI status codes (see
     MIDI Status Types):

    `MIDI_NOTEON'
          Note On Event.  `byte1' holds the numeric value of the note
          to play, while `byte2' holds the velocity of the note.  Both
          numbers range from 0 to 127.  Middle C is 60.  If the note is
          in the PipeLine, there are two separate events that describe
          it: a `MIDI_NOTEON' and a `MIDI_NOTEOFF' event.  If the Note
          is in a sequence, it is represented by one `MIDI_NOTEON'
          Event that holds a note duration in addition to the note
          value and velocity (see Note Events.) Unlike the MIDI spec, a
          `MIDI_NOTEOFF' Event may not be represented by a
          `MIDI_NOTEON' with a velocity of 0.

    `MIDI_NOTEOFF'
          Note Off Event.  `byte1' holds the numeric value of the note
          to stop playing, while `byte2' is ignored.

    `MIDI_PTOUCH'
          Polyphonic Key Pressure Event.  `byte1' holds the numeric
          value of the note, while `byte2' holds its key pressure, a
          value from 0 to 127.

    `MIDI_CCHANGE'
          Control Change Event.  There are 121 types of Continuous
          Controller Events.  `byte1' specifies the Control Change
          type.  For example, 1 indicates the modulation wheel setting,
          7 indicates overall volume, and 10 indicates the pan setting.
          `byte2' carries the data, once again ranging from 0 to 127.
          Control Change types 121 through 127 are special cases.  Of
          importance to Bars&Pipes are 121, the all controllers off
          command, and 123, the all notes off command.  Bars&Pipes
          sends both of these down each PipeLine whenever the user
          stops the sequencer.

    `MIDI_PCHANGE'
          Program Change Event.  This command sets the Program, or
          Patch, that the synthesizer plays.  `byte1' carries the
          Program, a number from 0 to 127, and `byte2' is ignored.

    `MIDI_MTOUCH'
          Monophonic Key Pressure Event.  Like `MIDI_PTOUCH', this
          broadcasts the key pressure, but for the keyboard as a whole,
          rather than on a note-by-note basis.  `byte1' carries the key
          pressure and `byte2' is not used.

    `MIDI_PBEND'
          Pitch Bend Event.  This transmits the current position of the
          Pitch Bend wheel.  Pitch Bend is a high resolution number,
          ranging from 0, for a complete bend down, to 0x3FFF for the
          maximum bend up.  A center pitch bend (no change) is 0x2000.
          The bend value is broken into two components, the high seven
          bits and the low seven bits of the bend.  The high bits are
          stored in `byte2', the low bits in byte.

`data'
     This is really just padding; however, if this is a `NoteEvent'
     structure (see Note Events) the upper two bytes carry the note
     duration.

`tool'
     This points to the Tool that is to process the Event.